Rime 输入法
Table of Contents
由李守中维护的 Rime 输入法方案可以 从此链接 找到。
1. 有关输入效率的思考
1.1. 用什么输入法
云词库技术让拼音输入法的重码率大大降低,拼音输入法的准确率越来越高,拼音输入法也渐渐成为了主流输入法。但是要使用云词库功能的话,输入法就必须上传用户键入的内容到服务器,这就带来了隐私问题。除此之外,目前主流中文输入法的广告问题也极为烦人。
Rime 输入法引擎完全开源,没有隐私问题。同时,由于其跨平台的特性,用户可以在所有支持的平台上有基本一致的输入体验。
相应地,它没有云词库可用,输入效率上会有些许损失。但是,李守中认为,隐私问题更加重要。
所以,李守中决定使用 Rime 为自己定制一套输入方案,在做到尽可能地提高输入效率的同时,还要方便在各个操作系统间迁移使用。
1.2. 选什么方案
现在主流的输入方案可以分成音码 (比如拼音输入法) 方案和形码 (比如五笔输入法) 方案两类。
使用五笔输入法需要理解并记忆一套全新的,以字根为基本单位的构建汉字的方式。而受中国大陆在义务教育阶段使用拼音作为普通话教学工具的影响,多数人都可以掌握以拼音为注音方式的汉字的普通话发音,这就让全拼输入法没有了使用门槛。
对于古汉语输入的需求让李守中选择五笔输入法 (86 版) 作为主方案;对于和网友吹牛逼时打字速度的需求让李守中选择自然码双拼作为辅助方案 (由于双拼在处理时会被映射到全拼上,所以输入方案也含有全拼);英文输入可以用 easy_en 方案解决;生僻字反查可以用 Rime 官方的笔划输入法;快速输入中文数字的需求则可以根据 Rime 官方的 数字之道 魔改出一个方案。在介绍方案与码表的章节有更多的信息。
1.2.1. 音码
汉语使用音调来确认语义的方式,叠加广泛存在的多音字,让拼音输入法的重码率极高。
全拼输入法使用汉字的全部拼音字母作为输入,确定一个发音需要按键多次。为了提高拼音输入法的输入效率,双拼输入法诞生了。它将汉字发音中的声母和韵母拆分,并映射到两个键位上。这种输入法只需要分别按下声母和韵母的所在按键 (按键 2 次) 就可以确定一个发音。双拼的输入效率,不论什么方案,都要比全拼的效率更高,这点毫无疑问。
但遗憾的是,双拼输入法只减少了击键次数,重码问题依旧极为严重。
云词库的本质可以理解为一个巨大的词库,但是这个词库并不是越大越好,词库增大到一定程度之后,增加词条的同时也会增加重码率,反而降低输入效率。
所以,李守中决定使用一个基础词库 + 一个大词库 (根据维基百科中文词条制作,有 129 万词条,39 MB 大小) 来尽可能地覆盖常用的词语。而在音码方案上,李守中选择应用范围最广的自然码作为输入方案。另外提一下,多数双拼方案都是根据自然码方案修改而来。
但是,古汉语输入效率底下的问题,在音码方案下几乎无解。生僻字叠加生僻词,使用音码输入法的话,多数时间都会花费在选词上,这个问题无法通过使用大词库来解决,只能使用形码。
1.2.2. 形码
形码方案主要有五笔、郑码、仓颉等。目前,大陆主流且没有版权问题的形码方案主要有 86 五笔和 98 五笔 (2019 年专利过期)。
86 五笔拆字不规范广为人知,但正是这些不规范大大减少了单字重码,使得单字重码率随之也大大下降;而 98 版的大字根多,打词组会轻松不少。但由于 86 五笔的发布较早,是很多系统默认的五笔输入方案;同时,许多的第三方输入法,只要它支持五笔输入法,那么它一定支持 86 五笔。于是 86 版五笔几乎成了事实上的形码标准。
此外,即便五笔输入法有重码率低的优势,几乎每一个字都有唯一的编码,这解决了输入古汉语时的生僻字问题,但在词组输入方面的重码率依然比较高。而使用型码要解决的主要问题就是重码率问题。
有人提出了不使用五笔输入法打词组,使用纯单字输入的思路,而这个思路只考虑了重码问题,在日常情境中使用纯单字输入效率并不高。相比于纯单字输入,更不建议使用大词库。词库大意味着重码多,这背离了形码的本义,把用户困在了当前词库里,换台电脑就束手束脚。
如何让单字和词组在兼顾各种输入情境的同时,还能较快输入的问题在 21 世纪初就有了定论: 单字配小词库的输入效率最高。
由于汉字体系中几乎不再增加新字,目前可以显示的字符基本已经被编入码表了,而不能显示的汉字则没有编入码表的必要。所以,单字码表的维护工作几乎为零。至于词库则需要两类,一类是由通用词组成的基础小词库,另一类是用户自行维护,经常增减词条的用户词库。这样可以在提供一定程度的灵活性的同时,最大程度地缓解输入时的重码情况。
结合以上因素,最终,李守中决定使用 86 版五笔作为唯一的形码输入法,使用以单字为主、两个小词库为辅的输入思路。
1.2.3. 音形双码
代表作为小鹤音形、二笔输入法等。自然码方案后来也加了形码,但没有推广开。这类方案用音码来确认发音,用形码来减少重码,是很不错的方案。但由于这些输入法的码表不开源,所以没办法在 Rime 中使用。李守中维护的方案中也没有音形双码的方案。
1.3. 候选项的展示形式
要关注的是候选项的数量和排序方式。推荐使用 5 个候选项与竖排方式。
使用 5 个候选项主要是基于左右手分工考虑。左手负责选择候选项 (数字 1 到 5),右手负责翻页 (逗号和句号翻页),这样可以尽可能少地减少双手的移动距离,提高输入效率。
对于使用形码的用户来说,输入的最大单位是词组,最小单位是单字。候选项长度较小。不论是横排还是竖排,都可以做到不用转动头部,仅移动视线就能浏览所有的候选项。
而使用音码的用户则可能会输入多个词组,甚至一个整句。此时如果使用横排,多个较长的候选项所占用的空间就会非常长,需要移动头部才能浏览所有的候选项。而使用竖排则可以减少候选栏长度,减少头部移动,从而提高输入效率。
因此,为了兼容音码方案,推荐使用竖排方式排列候选项。
2. 输入法方案及其码表
2.1. 五笔方案
五笔输入法使用 86 版,词库主体采用大单字库 + 小词库的方案。
Rime 官方的 86 五笔词库 rime-wubi 来源于 acevery/ibus-table-wubi 项目 ,但由于上游词库的码表里有很多错误的编码,直到 2015 年才被 Rime 用户发现并被 Rime 官方修复,详情见此。针对错误编码的补丁只存在于 Rime 官方的 rime-wubi 词库中,没有被反馈给上游的 ibus-table-wubi。这个词库错误较多,缺少维护,故不考虑使用。
另一个没有版权问题的词库是窝子 (Wozy) 创建的极爽词库,窝子在 2020 年将极爽五笔词库授权给了 Rime 官方使用,详情见此。但是极爽词库已经很久没有维护过了,因此极爽词库中的码表所包含的汉字也并不全面,只有 11589 个,在输入古汉语时经常找不到字。
目前可以找到的比较完整的码表是 Windows 10 操作系统自带的微软五笔的码表,共计 31900 个字。微软(中国)有限公司也是 GB 18030-2022 的起草单位,自家产品应该会遵循自家标准。所以本方案的五笔方案部分将使用此码表。
但微软五笔码表一共有 534114 个词条,去除单字后还有 502214 个词条,不符合小词库的要求。又考虑到,虽然极爽词库收录的单字并不全面,但它的常用词词库已经非常成熟,所以把极爽词库中的单字部分去除保留词组部分可以直接得到一个小体积的词库。
所以最终词库码表的组成是: 微软五笔的单字码表 + 极爽词库的多字词码表。
要导出 Win10 86 五笔的码表,需要打开 WubiLex (五笔助手) 软件,右键点击 系统码表(五笔86) ,选择 导出文本格式码表 保存为文本文件。有需要的读者也可以从此链接下载 已导出的 Win10 86 五笔码表 。
接着制作只包含单字的词库: 先删除文件中包含的词组,再调整列顺序。
使用 awk 互换两列 (使得码列在后,字列在前):
awk 'BEGIN {OFS="\t"} {temp = $1; $1 = $2; $2 = temp; print $0}' win10_1809_wubi_86.txt > new.txt
使用 awk 删除第一列 (字列) 中包含了词组的条目:
awk '{if (length($1) == 1) {print $0}}' new.txt > wubi_86_win10_single.dict.yaml
注: Rime 官方给的示例词库是字列在码列之前,但也可以通过 <dictionary>.dict.yaml 文件中 columns 字段来修改每一列的定义,来让码列在字列之前,从而避免修改导出的码表。此处为了和官方的示例保持一致,所以把词库处理为字列在码列之前。
到这里词库的单字部分就做好了,下面从极爽五笔的词库中删除单字,获得它的词库。
在提取词库之前,需要确定极爽词库的版本,有两个可以选择的词库,一个是让极点五笔成名的极爽 4.3 词库,另一个是从极爽 4.3 改进来的极爽 6.0 词库。考虑到时极爽 4.3 比 6.0 出名得多,所以决定使用极爽 4.3 作为小词库的来源。极爽 4.3 词库中共有 88543 个词条,其中包含 61432 个词组,符合小词库的要求。可以从此链接下载 极爽词库 (包含 4.3 和 6.0 词库)。
使用 awk 来生成去掉单字的词库:
# 从极爽 4.3 词库生成去掉单字的码表,同时交换字列和码列 awk '{if (NR<=11) next;} {if (length($2) > 1) print $0}' jishuang43.txt | awk '{if ($1 ~ /^zz.*255/) next; else print $2"\t"$1"\t"$3;}' > wubi_86_jishuang_phrase.dict_with_freq.yaml # 从极爽 4.3 词库生成去掉单字的码表,同时交换字列和码列。如果不想要词频就用下面这行 awk '{if (NR<=11) next;} {if (length($2) > 1) print $0}' jishuang43.txt | awk '{if ($1 ~ /^zz.*255/) next; else print $2"\t"$1;}' > wubi_86_jishuang_phrase.dict.yaml # 从极爽 6.0 词库生成去掉单字的码表,同时交换字列和码列 awk '{if (NR<=10) next;} {if (length($2) > 1) print $0}' jishuang43.txt | awk '{if ($1 ~ /^zz.*255/) next; else print $2"\t"$1"\t"$3;}' > wubi_86_jishuang_phrase.dict_with_freq.yaml # 从极爽 6.0 词库生成去掉单字的码表,同时交换字列和码列。如果不想要词频就用下面这行 awk '{if (NR<=10) next;} {if (length($2) > 1) print $0}' jishuang43.txt | awk '{if ($1 ~ /^zz.*255/) next; else print $2"\t"$1;}' > wubi_86_jishuang_phrase.dict.yaml
把极爽词库中单字的词频迁移到 win10 码表的单字上,可以用这段 Python 脚本来实现:
jishuang_f = open("jishuang43.txt", "r", encoding='UTF-8')
win10wubi_f = open("wubi_86_win10_single.dict.yaml", "r", encoding='UTF-8')
jishuang = []
win10wubi = []
for line in jishuang_f:
if "\t" in line:
jishuang.append(line.replace("\n", "").split("\t"))
for line in win10wubi_f:
if "\t" in line:
win10wubi.append(line.replace("\n", "").split("\t"))
for win_item in win10wubi:
for js_item in jishuang:
if js_item[1] == win_item[0]:
win_item.append(js_item[2])
print(win_item)
break
final_content = ""
for item in win10wubi:
final_content += ("\t".join(item) + "\n")
win10wubi_with_freq_f = open("wubi_86_win10_single_with_freq.dict.yaml", "w", encoding='UTF-8')
win10wubi_with_freq_f.write(final_content)
可以直接下载 处理好的词库文件 。
给 wubi_86_win10_single.dict.yaml 和 wubi_86_jishuang_phrase.dict.yaml 分加上码表配置字段即为可被 Rime 使用的词库。(将排序方式改为 original ,即原始顺序,可使词频失效)
最终,五笔方案的词库构成为:
- 词库主体:
- 微软五笔词库的单字码表
- 极爽 4.3 词库的多字词码表
- 其他词库:
- KyleBing/rime-wubi86-jidian 中取行政区划词库码表
- 用户私有词库码表
2.2. 拼音方案
拼音输入法使用双拼 (自然码) 和全拼两种方案,可以自行切换。
双拼输入法在解析时会被映射到全拼上面,所以双拼输入法没有自己的词库。
最终,全拼词库的构成为:
- 词库主体:
- Rime 官方的袖珍简化字 rime-pinyin-simp 方案的词库 (上游词库为安卓开源项目)
- 维基百科中文词条库 https://github.com/felixonmars/fcitx5-pinyin-zhwiki
- 其他词库
- 用户私有词库
2.3. 其他方案
英文输入法来源于 easy_en 项目,作者为 Patricivs。
笔画输入法来源于 Rime 官方的 rime-stroke 方案,主要用于反查。
中文数字输入法根据 Rime 官方教程 数字之道 修改而来。